package docker

//分片 + 高可用 + 负载均衡
//看图  images/100-docker部署redis集群.png
//停止正在运行的容器并删除
// docker stop $(docker ps -aq) && docker rm $(docker ps -aq)

/*
	集群
		1.建立redis网卡
		2.使用shell脚本一次性修改redis的配置文件
		3.启动容器
		4.进入容器，创建集群
 		5.进入集群查看信息
		6.操作集群，停掉一个master等




--------------------建立redis网卡--------------------
	//先为集群建立一个网卡
	docker network create --driver bridge --subnet 173.38.0.0/16 --gateway 173.38.0.1 redis-colony
	or
	docker network create  --subnet 173.38.0.0/16 redis-colony1


--------------------使用shell脚本一次性修改redis的配置文件--------------------
	#循环6次
	for port in $(seq 1 6); \
	do \
	#创建配置文件目录
	mkdir -p /home/zydh/docker/etc/redis/node-${port}/conf
	#创建conf配置文件
	touch /home/zydh/docker/etc/redis/node-${port}/conf/redis.conf
	# 写入具体配置到conf中
	cat << EOF >/home/zydh/docker/etc/redis/node-${port}/conf/redis.conf
	port 6379
	bind 0.0.0.0
	#集群的核心，开启
	cluster-enabled yes
	cluster-config-file nodes.conf
	cluster-node-timeout 5000
	#链接具体的ip
	cluster-announce-ip 173.38.0.1${port}
	cluster-announce-port 6379
	cluster-announce-bus-port 16379
	appendonly yes
	EOF
	done


无注释版，记得修改 mkdir -p 和 touch 下的路径

for port in $(seq 1 6); \
do \
mkdir -p /home/zydh/docker/etc/redis/node-${port}/conf
touch /home/zydh/docker/etc/redis/node-${port}/conf/redis.conf
cat << EOF >/home/zydh/docker/etc/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 173.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

上面是在liunx上，在debian上

	1.touch redis-cluster-shell
	2. vim redis-cluster-shell
	3.在文件顶部输入 #！/bin/bash
	4.此时就可以写你要在脚本中编写的内容了
	5.编写玩保存文件，并更改文件的权限 在root用户下 chmod 777 redis-cluster-shell
	6.此时redis-cluster-shell就是一个可执行的脚本文件了
	7.  ./redis-cluster-shell就可以执行了


	以下是编写的shell脚本

root@VM-4-8-debian:/home/zydh/docker/etc# chmod 777 redis-cluster-shell
root@VM-4-8-debian:/home/zydh/docker/etc# cat redis-cluster-shell
#! /bin/bash
for port in $(seq 1 6);
do
mkdir -p /home/zydh/docker/etc/redis/node-${port}/conf
touch /home/zydh/docker/etc/redis/node-${port}/conf/redis.conf
cat << EOF >/home/zydh/docker/etc/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 173.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
root@VM-4-8-debian:/home/zydh/docker/etc#






--------------------启动容器--------------------


	docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
	-v /home/zydh/docker/volume/redis/node-1/data:/data \
	-v /home/zydh/docker/etc/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
	-d --net redis-colony --ip 173.38.0.11 redis redis-server /etc/redis/redis.conf



		[root@VM_0_13_centos conf]# docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
		> redis.conf -v /home/zydh/docker/volume/redis/node-1/data:/data \
		> redis.conf -v /home/zydh/docker/etc/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
		> redis.conf -d --net redis-colony --ip 173.38.0.11 redis redis-server /etc/redis/redis.conf
		Unable to find image 'redis.conf:latest' locally
		docker: Error response from daemon: pull access denied for redis.conf, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
		See 'docker run --help'.
		[root@VM_0_13_centos conf]# cd /	跳出当前文件夹





	docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
	-v /home/zydh/docker/volume/redis/node-2/data:/data \
	-v /home/zydh/docker/etc/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
	-d --net redis-colony --ip 173.38.0.12 redis redis-server /etc/redis/redis.conf

	docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
	-v /home/zydh/docker/volume/redis/node-3/data:/data \
	-v /home/zydh/docker/etc/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
	-d --net redis-colony --ip 173.38.0.13 redis redis-server /etc/redis/redis.conf

	docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
	-v /home/zydh/docker/volume/redis/node-4/data:/data \
	-v /home/zydh/docker/etc/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
	-d --net redis-colony --ip 173.38.0.14 redis redis-server /etc/redis/redis.conf

	docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
	-v /home/zydh/docker/volume/redis/node-5/data:/data \
	-v /home/zydh/docker/etc/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
	-d --net redis-colony --ip 173.38.0.15 redis redis-server /etc/redis/redis.conf

	docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
	-v /home/zydh/docker/volume/redis/node-6/data:/data \
	-v /home/zydh/docker/etc/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
	-d --net redis-colony --ip 173.38.0.16 redis redis-server /etc/redis/redis.conf



--------------------进入容器，创建集群--------------------

	docker exec -it redis-1 /bin/bash

	//创建集群
	redis-cli --cluster create 173.38.0.11:6379 173.38.0.12:6379 173.38.0.13:6379 173.38.0.14:6379 173.38.0.15:6379 173.38.0.16:6379 --cluster-replicas 1

				--cluster create  			创建一个集群
				--cluster-replicas 1		表示主从比例1，即一个主节点对应一个从节点，先主后从


	Node 173.38.0.12:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
	https://blog.csdn.net/qq_37300273/article/details/77267377
	删除nodes-xxx.conf配置文件，删除pid文件，删除各节点aof,rdb文件,杀掉所有redis进程，然后重启redis集群搞定
	https://blog.csdn.net/xinyuanjieyiwife/article/details/109581272
		解决办法：
		1，先kill redis创建的集群节点进程
		2，删除每个redis节点的appendonly.aof文件，dump.rdb文件，nodes.conf文件
		并且执行./redis-cli flushdb 命令，清空每个redis里面的数据。
		3，重启每个redis节点，再执行集群操作即可

	docker exec -it redis-[123456] /bin/bash
	ls
	//rm -f /data/\*
	退出，在删除之前用代码创建的/mydata文件夹


root@VM-4-8-debian:/home/zydh/docker# docker exec -it redis-1 /bin/bash
root@75332c57aac0:/data# ls
appendonly.aof	nodes.conf
root@75332c57aac0:/data# redis-cli --cluster create 173.38.0.11:6379 173.38.0.12:6379 173.38.0.13:6379 173.38.0.14:6379 173.38.0.15:6379 173.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...		## 哈希槽 hash slots 对着6个节点进行了分配
Master[0] -> Slots 0 - 5460								## 哈希槽  看图 images/docker-121-redis集群-3主3从-哈希槽hash slot-02.png
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 173.38.0.15:6379 to 173.38.0.11:6379
Adding replica 173.38.0.16:6379 to 173.38.0.12:6379
Adding replica 173.38.0.14:6379 to 173.38.0.13:6379
M: 3b290e9bd54275e09b43baa894048ce43fd733a3 173.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: 4237302b95c391e43d0ca5da2d4b08b3d3727621 173.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 88a3230a9156b2e870798dd3ef653a0c95a14a14 173.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: e05c4e1b53a4c4b5e33a17e44a81f2e4ee24ec21 173.38.0.14:6379
   replicates 88a3230a9156b2e870798dd3ef653a0c95a14a14
S: e4cda5814f612b1aeea2d808bcb2a4e73741abd7 173.38.0.15:6379
   replicates 3b290e9bd54275e09b43baa894048ce43fd733a3
S: 8f5383e60ada7e53279d113ded66b4c07fb054a0 173.38.0.16:6379
   replicates 4237302b95c391e43d0ca5da2d4b08b3d3727621
Can I set the above configuration? (type 'yes' to accept):

## 这里输入yes
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.			### 16384 个哈希槽全部覆盖
root@75332c57aac0:/data#


	哈希槽为 看 docker-1000-1003*



--------------------进入集群操作--------------------

	操作，一定要【-c】，-c代表的是集群，redis-cli只是单机
	root@75332c57aac0:/data#  redis-cli -c
	127.0.0.1:6379>


	查看集群信息
	127.0.0.1:6379> cluster info


127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3			##集群数量3，主从复制
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:480
cluster_stats_messages_pong_sent:491
cluster_stats_messages_sent:971
cluster_stats_messages_ping_received:486
cluster_stats_messages_pong_received:480
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:971
127.0.0.1:6379>


		查看节点，三主三从
		127.0.0.1:6379> cluster nodes


127.0.0.1:6379> cluster nodes
8f5383e60ada7e53279d113ded66b4c07fb054a0 173.38.0.16:6379@16379 slave 4237302b95c391e43d0ca5da2d4b08b3d3727621 0 1664468024184 2 connected
4237302b95c391e43d0ca5da2d4b08b3d3727621 173.38.0.12:6379@16379 master - 0 1664468024000 2 connected 5461-10922
88a3230a9156b2e870798dd3ef653a0c95a14a14 173.38.0.13:6379@16379 master - 0 1664468024685 3 connected 10923-16383
e05c4e1b53a4c4b5e33a17e44a81f2e4ee24ec21 173.38.0.14:6379@16379 slave 88a3230a9156b2e870798dd3ef653a0c95a14a14 0 1664468023682 3 connected
3b290e9bd54275e09b43baa894048ce43fd733a3 173.38.0.11:6379@16379 myself,master - 0 1664468024000 1 connected 0-5460
e4cda5814f612b1aeea2d808bcb2a4e73741abd7 173.38.0.15:6379@16379 slave 3b290e9bd54275e09b43baa894048ce43fd733a3 0 1664468024000 1 connected
127.0.0.1:6379>



第5行和第6行 提炼出来==>

3b290e9bd54275e09b43baa894048ce43fd733a3 173.38.0.11:6379@16379 myself,master - 0 1664468024000 1 connected 0-5460
										 173.38.0.15:6379@16379 slave 3b290e9bd54275e09b43baa894048ce43fd733a3 0 1664468024000 1 connected

		==>
3b290e9bd54275 173.38.0.11:6379@16379 myself,master
			   173.38.0.15:6379@16379 slave 3b290e9bd54275

		==>
3b290e9bd54275 myself,master
			   slave 3b290e9bd54275

		==>
			非常明显的可以看到 谁是主机，谁是从机




--------------------操作集群--------------------
			这里可以看 docker-121* 里面更详细


		往集群里面添加值
		set root zydh

127.0.0.1:6379> set root zydh
-> Redirected to slot [15680] located at 173.38.0.13:6379  ##此处由 .13 处理，对比上面的节点，是13的master节点
OK
173.38.0.13:6379>



		然后另开一个xshell链接，停掉.13的容器redis-3

root@VM-4-8-debian:~# docker stop redis-3
redis-3
root@VM-4-8-debian:~#


		然后回到该xshll，退出，在连接，获取刚才set root

173.38.0.13:6379> get root     ##这里有问题，因为redis-3停止了，这里还在redis-3里面操作，需要重新进入集群一次
Error: Connection timed out
root@75332c57aac0:/data# redis-cli -c
127.0.0.1:6379> get root
-> Redirected to slot [15680] located at 173.38.0.14:6379  ##.14服务器get到
"zydh"
173.38.0.14:6379>


		查看集群节点信息  .13 master,fail  显示故障转移  .14 myself,master 已经变成了master
		cluster nodes

173.38.0.14:6379> cluster nodes
e4cda5814f612b1aeea2d808bcb2a4e73741abd7 173.38.0.15:6379@16379 slave 3b290e9bd54275e09b43baa894048ce43fd733a3 0 1664468798000 1 connected
e05c4e1b53a4c4b5e33a17e44a81f2e4ee24ec21 173.38.0.14:6379@16379 myself,master - 0 1664468796000 7 connected 10923-16383
88a3230a9156b2e870798dd3ef653a0c95a14a14 173.38.0.13:6379@16379 master,fail - 1664468522830 1664468521000 3 disconnected
4237302b95c391e43d0ca5da2d4b08b3d3727621 173.38.0.12:6379@16379 master - 0 1664468797547 2 connected 5461-10922
8f5383e60ada7e53279d113ded66b4c07fb054a0 173.38.0.16:6379@16379 slave 4237302b95c391e43d0ca5da2d4b08b3d3727621 0 1664468798549 2 connected
3b290e9bd54275e09b43baa894048ce43fd733a3 173.38.0.11:6379@16379 master - 0 1664468798750 1 connected 0-5460
173.38.0.14:6379>


		集群高可用成功

		另一个再次开启redis-3

root@VM-4-8-debian:~# docker start redis-3
redis-3
root@VM-4-8-debian:~#


			另一个xshell链接中  ，发现.13变成了.14的从机

[root@VM_0_13_centos /]#
173.38.0.14:6379>
root@c9bd957ed44c:/data# redis-cli -c
127.0.0.1:6379> cluster nodes
5a6a79b50cd829e712d88a0ecf26fb46d4445663 173.38.0.16:6379@16379 slave 84b22a0592dc25fc3a3b21b613b27a1e5dc22792 0 1614309563939 2 connected
e729d5d2069c74bf61cadf47fc370d9d1bcca2eb 173.38.0.13:6379@16379 slave e268d75b2744663e19367c1140e6b63b5df06afa 0 1614309565000 7 connected
bc6a2184d0596f97c1c0440f1062f33169343365 173.38.0.15:6379@16379 slave 4ddf8e94a52400a28f040782958bdf5a983641d4 0 1614309564943 1 connected
84b22a0592dc25fc3a3b21b613b27a1e5dc22792 173.38.0.12:6379@16379 master - 0 1614309565946 2 connected 5461-10922
e268d75b2744663e19367c1140e6b63b5df06afa 173.38.0.14:6379@16379 master - 0 1614309565000 7 connected 10923-16383
4ddf8e94a52400a28f040782958bdf5a983641d4 173.38.0.11:6379@16379 myself,master - 0 1614309564000 1 connected 0-5460
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 173.38.0.14:6379
"1"
173.38.0.14:6379> set b
(error) ERR wrong number of arguments for 'set' command
173.38.0.14:6379> set b2
(error) ERR wrong number of arguments for 'set' command
173.38.0.14:6379> set b 2
-> Redirected to slot [3300] located at 173.38.0.11:6379
OK
173.38.0.11:6379> get b
"2"
173.38.0.11:6379>



*/
